package com.company.cloud.coupon.client;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

import com.company.cloud.common.bean.BaseClientResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;

import com.company.cloud.common.bean.LoginSimpleUserInfo;
import com.company.cloud.common.exception.BusinessException;
import com.company.cloud.common.utils.LocalDateTimeUtils;
import com.company.cloud.coupon.constant.CouponConstant.CouponStateEnum;
import com.company.cloud.coupon.constant.CouponErrorEnum;
import com.company.cloud.coupon.modules.api.request.CouponOrderItem;
import com.company.cloud.coupon.modules.api.request.Lock2UseCouponRequest;
import com.company.cloud.coupon.modules.api.request.LockCouponRequest;
import com.company.cloud.coupon.modules.api.request.UnLockCouponRequest;
import com.company.cloud.coupon.modules.api.request.Use2notCouponRequest;
import com.company.cloud.coupon.modules.api.request.UseCouponRequest;
import com.company.cloud.coupon.modules.api.response.LockCouponResponse;
import com.company.cloud.coupon.modules.api.response.UseCouponResponse;
import com.company.cloud.coupon.modules.api.service.CouponRemoteService;
import com.company.cloud.coupon.modules.app.service.CouponService;
import com.company.cloud.coupon.modules.base.entity.CouponInfo;
import com.company.cloud.coupon.modules.base.service.CouponInfoService;

@RestController
@Service
public class CouponRemoteServiceImpl implements CouponRemoteService {
	@Autowired
	private CouponService couponService;
	@Autowired
	private CouponInfoService couponInfoService;
	/**
	 * 锁定优惠券
	 */
	@Override
	public BaseClientResult<LockCouponResponse> lockCoupon(LockCouponRequest param) {
		try {
			BigDecimal fund= this.calCoupon(param.getCouponNo(), param.getItems(),
					CouponStateEnum.Lock_CouponState, param.getUserInfo());
			LockCouponResponse data= new LockCouponResponse(fund);
			return BaseClientResult.success(data);
		}catch (Exception e){
			return BaseClientResult.error(e);
		}

	}

	/**
	 * 解除锁定优惠券
	 */
	@Override
	public  BaseClientResult<String> unLockCoupon(UnLockCouponRequest param) {
		try {
			CouponInfo coupon=couponInfoService.getById(param.getCouponNo());
			if(coupon==null) {
				throw new BusinessException(CouponErrorEnum.Coupon_Null);
			}
			if(!CouponStateEnum.Lock_CouponState.getCode().equals(coupon.getState())) {
				throw new BusinessException(CouponErrorEnum.Coupon_State_Not_Op);
			}
			coupon.setState(CouponStateEnum.Not_CouponState.getCode());
			coupon.setUsableDate(LocalDateTime.now());
			coupon.setUsableIp(param.getUserInfo().getIp());
			coupon.addEditParam(param.getUserInfo());
			couponInfoService.updateById(coupon);
			return BaseClientResult.success();
		}catch (Exception e){
			return BaseClientResult.error(e);
		}
	}

	/**
	 * 锁定优惠券转使用
	 */
	@Override
	public  BaseClientResult<String> lock2UseCoupon(Lock2UseCouponRequest param) {
		try {
			CouponInfo coupon=couponInfoService.getById(param.getCouponNo());
			if(coupon==null) {
				throw new BusinessException(CouponErrorEnum.Coupon_Null);
			}
			if(!CouponStateEnum.Not_CouponState.getCode().equals(coupon.getState())) {
				throw new BusinessException(CouponErrorEnum.Coupon_State_Not_Op);
			}
			coupon.setState(CouponStateEnum.Yes_Pay_CouponState.getCode());
			coupon.setUsableDate(LocalDateTime.now());
			coupon.setUsableIp(param.getUserInfo().getIp());
			coupon.addEditParam(param.getUserInfo());
			couponInfoService.updateById(coupon);
			return BaseClientResult.success();
		}catch (Exception e){
			return BaseClientResult.error(e);
		}



	}

	/**
	 * 直接使用优惠券
	 */
	@Override
	public BaseClientResult<UseCouponResponse> useCoupon(UseCouponRequest param) {
		try {
			BigDecimal fund= this.calCoupon(param.getCouponNo(),param.getItems(), CouponStateEnum.Yes_Pay_CouponState, param.getUserInfo());
			UseCouponResponse data= new UseCouponResponse(fund);
			return BaseClientResult.success(data);
		}catch (Exception e){
			return BaseClientResult.error(e);
		}
	}

	/**
	 * 使用优惠券退还
	 */
	@Override
	public  BaseClientResult<String> use2notCoupon(Use2notCouponRequest param) {
		try {
			CouponInfo coupon=couponInfoService.getById(param.getCouponNo());
			if(coupon==null) {
				throw new BusinessException(CouponErrorEnum.Coupon_Null);
			}
			if(CouponStateEnum.Yes_Pay_CouponState.getCode().equals(coupon.getState())
					|| CouponStateEnum.Yes_Scan_CouponState.getCode().equals(coupon.getState())) {
			}else {
				throw new BusinessException(CouponErrorEnum.Coupon_State_Not_Op);
			}
			coupon.setState(CouponStateEnum.Not_CouponState.getCode());
			coupon.setUsableDate(LocalDateTime.now());
			coupon.setUsableIp(param.getUserInfo().getIp());
			coupon.addEditParam(param.getUserInfo());
			couponInfoService.updateById(coupon);
			return BaseClientResult.success();
		}catch (Exception e){
			return BaseClientResult.error(e);
		}

	}

	
	/**
	 * 计算优惠券优惠金额和更新优惠券状态
	 * */
	private BigDecimal calCoupon(String couponNo, List<CouponOrderItem> items,CouponStateEnum state, LoginSimpleUserInfo userInfo) {
		CouponInfo coupon=couponInfoService.getById(couponNo);
		if(coupon==null) {
			throw new BusinessException(CouponErrorEnum.Coupon_Null);
		}
		if(!CouponStateEnum.Not_CouponState.getCode().equals(coupon.getState())) {
			throw new BusinessException(CouponErrorEnum.Coupon_Use);
		}
		if(LocalDateTimeUtils.compare(coupon.getStartDate(), LocalDateTime.now())>0) {
			throw new BusinessException(CouponErrorEnum.Coupon_StartDate);
		}
		if(LocalDateTimeUtils.compare(coupon.getEndDate(), LocalDateTime.now())<0) {
			throw new BusinessException(CouponErrorEnum.Coupon_EndDate);
		}
		BigDecimal couponFund=couponService.calCouponFund(coupon, items);
		if(couponFund.doubleValue()<=0) {
			throw new BusinessException(CouponErrorEnum.Coupon_NotUse);
		}
		coupon.setState(state.getCode());
		coupon.setUsableDate(LocalDateTime.now());
		coupon.setUsableIp(userInfo.getIp());
		coupon.addEditParam(userInfo);
		couponInfoService.updateById(coupon);
		return couponFund;
	}
	
	
}
